home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / mac / files / t_sys5 / unixcpio.gz / unixnet.cpio / command.asm < prev    next >
Assembly Source File  |  1994-07-11  |  11KB  |  523 lines

  1.     include    pmacros.h
  2. verify    equ    0
  3.  
  4. dseg
  5.   if verify
  6. verify_copy    db    1,2,3,4,5,6,7,8,9
  7.   endif
  8.     db    4096 dup(?)
  9. stack    label    byte
  10.   if verify
  11. verify_original    db    1,2,3,4,5,6,7,8,9
  12. verify_len    equ    $-verify_original
  13. verify_err    db    'Stack overflow','$'
  14.   endif
  15. dsegend
  16.  
  17. cseg
  18.  
  19. intds@    dw    dgroup
  20.  
  21. segoff    struc
  22. offs    dw    ?
  23. segm    dw    ?
  24. segoff    ends
  25.  
  26. their_8h    dd ?
  27. their_10h    dd ?
  28. their_13h    dd ?
  29. their_1Bh    dd ?
  30. their_21h    dd ?
  31. their_23h    dd ?
  32. their_24h    dd ?
  33. their_28h    dd ?
  34.  
  35. dos_segment    dw ?            ;segment of internal DOS flags
  36. indos_offset    dw ?            ;offset of INDOS flag
  37. errflag_offset    dw ?            ;offset of critical error flag
  38. program_status    db 0            ;popup status
  39. flag_10h    db 0            ;status of interrupt 10h
  40. flag_13h    db 0            ;status of interrupt 13h
  41. zflag        db ?            ;save and restore critical error.
  42. dos_version    db ?            ;dos major version.
  43. main_countdown    db 20
  44. ss_register    dw ?            ;SS register storage
  45. sp_register    dw ?            ;SP register storage
  46. my_psp        dw ?            ;our PSP.
  47. their_psp        dw ?            ;PSP segment storage
  48.  
  49. tick_counter    dw ?
  50. indos_counter    dw ?
  51. errflag_counter    dw ?
  52. status_counter    dw ?
  53. bp_counter    dw ?
  54. main_counter    dw ?
  55.  
  56.  
  57. their_dta    dd    ?
  58. ;
  59. ;------------------------------------------------------------------------------
  60. ;Interrupt 8 handling routine.
  61. ;------------------------------------------------------------------------------
  62. timer    proc near
  63.     pushf                ;call BIOS routine
  64.     call their_8h
  65.     inc tick_counter
  66.     cmp program_status,0        ;are we already running?
  67.     jne timer_status        ;yes, then suspend ticking.
  68.     cmp flag_10h,0            ;video flag set?
  69.     jne timer_exit            ;yes, then exit
  70.     cmp flag_13h,0            ;disk flag set?
  71.     jne timer_exit            ;yes, then exit
  72.     push es                ;save ES and DI
  73.     push di
  74.     mov es,dos_segment        ;check INDOS flag
  75.     mov di,indos_offset
  76.     cmp byte ptr es:[di],0
  77.     jne timer_indos            ;exit if it's set
  78.     mov di,errflag_offset        ;check critical error flag
  79.     cmp byte ptr es:[di],0
  80.     jne timer_errflag        ;exit if it's set
  81.     call main            ;call body of program
  82.     pop di
  83.     pop es
  84. timer_exit:
  85.     iret
  86. timer_indos:
  87.     inc indos_counter
  88.     pop di                ;restore registers
  89.     pop es
  90.     iret
  91. timer_errflag:
  92.     inc errflag_counter
  93.     pop di                ;restore registers
  94.     pop es
  95.     iret
  96. timer_status:
  97.     inc status_counter
  98.     iret
  99. timer    endp
  100. ;
  101. ;------------------------------------------------------------------------------
  102. ;Interrupt 10h handling routine.
  103. ;------------------------------------------------------------------------------
  104. video    proc near
  105.     pushf                ;push flags onto stack
  106.     inc flag_10h            ;increment flag
  107.     call their_10h            ;call BIOS routine
  108.     dec flag_10h            ;decrement flag
  109.     iret
  110. video    endp
  111. ;
  112. ;------------------------------------------------------------------------------
  113. ;Interrupt 13h handling routine.
  114. ;------------------------------------------------------------------------------
  115. my_13    proc far
  116.     pushf                ;push flags onto stack
  117.     inc flag_13h            ;set 'busy' flag
  118.     call their_13h            ;call BIOS routine
  119.     pushf                ;save output flags
  120.     dec flag_13h            ;clear flag
  121.     popf                ;restore output flags
  122.     ret 2                ;exit without destroying flags
  123. my_13    endp
  124. ;
  125. ;------------------------------------------------------------------------------
  126. ;Interrupt 28h handling routine.
  127. ;------------------------------------------------------------------------------
  128. my_28    proc near
  129.     pushf                ;call original routine
  130.     call their_28h
  131.     inc bp_counter
  132.     cmp flag_10h,0            ;video flag set?
  133.     jne bp_exit            ;yes, then exit
  134.     cmp flag_13h,0            ;disk flag set?
  135.     jne bp_exit            ;yes, then exit
  136.     push es                ;save ES and DI
  137.     push di
  138.     mov es,dos_segment        ;check critical error flag
  139.     mov di,errflag_offset
  140.     cmp byte ptr es:[di],0
  141.     pop di                ;clean up the stack
  142.     pop es
  143.     jne bp_errflag
  144.     call main            ;call main routine
  145. bp_exit:
  146.     iret                ;done - exit
  147. bp_errflag:
  148.     inc errflag_counter
  149.     iret                ;done - exit
  150. my_28    endp
  151.  
  152. ;
  153. ;------------------------------------------------------------------------------
  154. ;Interrupt 21h handling routine.
  155. ;------------------------------------------------------------------------------
  156. my_21    proc far
  157.     pushf                ;save the flags
  158.     or    ah,ah            ;Doing function zero?
  159.     je    jump_to_dos        ;If yes, take the jump
  160.     cmp    ah,4bh            ;Doing EXEC function?
  161.     je    jump_to_dos        ;If yes, take the jump
  162.     popf
  163.  
  164.     pushf
  165.     call    cs:their_21h        ;Do the DOS function
  166.  
  167.     pushf                ;Save the result flags
  168.     cmp    cs:program_status,0    ;are we already running?
  169.     jne    no_recursion        ;yes, don't recurse.
  170.     dec    cs:main_countdown
  171.     jne    no_recursion
  172.     mov    cs:main_countdown,20
  173.     call    main            ;Safe to access disk now
  174. no_recursion:
  175.     popf                ;Recover DOS result flags
  176.  
  177.     sti                ;Must return with interrupts on
  178.     ret    2            ;Return with DOS result flags
  179. jump_to_dos:
  180.     popf
  181.     jmp     cs:their_21h
  182.  
  183. my_21    endp
  184.  
  185. ;
  186. ;------------------------------------------------------------------------------
  187. ;Interrupt 24h handling routine (DOS 3.X only).
  188. ;------------------------------------------------------------------------------
  189. my_24    proc near
  190.     mov al,3            ;fail the call in progress
  191. ioexit:
  192.     iret                ;give control back to DOS
  193. my_24    endp
  194. ;
  195. ;------------------------------------------------------------------------------
  196. ;MAIN is the routine called periodically.
  197. ;------------------------------------------------------------------------------
  198. main    proc near
  199.     inc main_counter
  200.     push    ax
  201.     mov program_status,1        ;set program active flag
  202.     cli                ;make sure interrupts are off
  203.     mov ss_register,ss        ;save stack registers
  204.     mov sp_register,sp
  205.     mov ss,cs:intds@
  206.     mov sp,offset stack
  207.     sti                ;enable interrupts
  208.     push bx
  209.     push cx
  210.     push dx
  211.     push si
  212.     push di
  213.     push ds
  214.     push es
  215.     push bp
  216. ;
  217. ;Set DS and ES segment registers.
  218. ;
  219.     push cs                ;set DS to code segment
  220.     pop ds
  221.     dscode
  222.   if verify
  223.     call    check_stack
  224.   endif
  225. ;
  226. ;Save the current active PSP address and activate this PSP.
  227. ;
  228.     mov zflag,0            ;clear flag
  229.     cmp dos_version,2        ;DOS version 2.X?
  230.     jne main5
  231.     mov es,dos_segment        ;point ES:DI to INDOS
  232.     mov di,indos_offset
  233.     cmp byte ptr es:[di],0        ;INDOS clear?
  234.     je main5            ;yes, then branch
  235.     mov di,errflag_offset        ;point ES:DI to error flag
  236.     cmp byte ptr es:[di],0        ;critical error flag clear?
  237.     jne main5            ;no, then branch
  238.     mov byte ptr es:[di],1        ;set critical error flag manually
  239.     mov zflag,1            ;set change flag
  240. main5:
  241.     mov ah,51h            ;get current PSP segment
  242.     int 21h
  243.     mov their_psp,bx            ;save it
  244.  
  245.     mov ah,50h            ;make this the active PSP
  246.     mov bx,my_psp
  247.     int 21h
  248.  
  249.     cmp zflag,0            ;ZFLAG clear?
  250.     je main6            ;yes, then branch
  251.     mov di,errflag_offset        ;point ES:DI to error flag
  252.     mov byte ptr es:[di],0        ;restore error flag value
  253. main6:
  254. ;
  255. ;Reset the interrupt 1Bh, 23h, and 24h vectors.
  256. ;
  257.     call ioset            ;reset interrupt vectors
  258. ;
  259. ;Save the current dta and subdirectory
  260. ;
  261.     mov    ah,2fh            ;get disk transfer address
  262.     int    21h
  263.     mov    their_dta.segm,es
  264.     mov    their_dta.offs,bx
  265.  
  266. ;
  267. ;Call the commutator loop of net until nothing gets queued up.
  268. ;
  269.     mov    ds,intds@
  270.     assume    ds:nothing
  271.     extproc    cycle
  272.     call    cycle@
  273. ;
  274. ;Restore the current dta and subdirectory
  275. ;
  276.     lds    dx,their_dta
  277.     mov    ah,1ah
  278.     int    21h
  279.  
  280. ;
  281. ;Restore interrupt vectors and former active PSP.
  282. ;
  283.     mov ah,50h            ;restore active PSP label
  284.     mov bx,their_psp
  285.     int 21h
  286.     call ioreset            ;restore interrupt vectors
  287. ;
  288. ;Restore registers and stack before exit.
  289. ;
  290.     pop bp                ;restore registers and exit
  291.     pop es
  292.     pop ds
  293.     pop di
  294.     pop si
  295.     pop dx
  296.     pop cx
  297.     pop bx
  298.     cli                ;interrupts off
  299.     mov ss,ss_register        ;switch to original stack
  300.     mov sp,sp_register
  301.     sti                ;interrupts on
  302.     pop ax
  303.     mov program_status,0        ;clear status flag
  304.     ret
  305. main    endp
  306. ;
  307. ;------------------------------------------------------------------------------
  308. ;IOSET vectors interrupts 1Bh, 23h and 24h to internal handlers.  IORESET
  309. ;restores the original vector values.
  310. ;------------------------------------------------------------------------------
  311. ioset    proc near
  312.     dscode
  313.     push es                ;save ES
  314.     mov ax,351Bh            ;get interrupt 1Bh vector
  315.     int 21h
  316.     mov their_1Bh.segm,es        ;save it
  317.     mov their_1Bh.offs,bx
  318.     mov ah,25h            ;point it to an IRET instruction
  319.     mov dx,offset ioexit
  320.     int 21h
  321.     mov ax,3523h            ;get interrupt 23h vector
  322.     int 21h
  323.     mov their_23h.segm,es        ;save it
  324.     mov their_23h.offs,bx
  325.     mov ah,25h            ;point it to an IRET instruction
  326.     mov dx,offset ioexit
  327.     int 21h
  328.     mov ax,3524h            ;get interrupt 24h vector
  329.     int 21h
  330.     mov their_24h.segm,es        ;save it
  331.     mov their_24h.offs,bx
  332.     mov ah,25h            ;then set it to IOERR routine
  333.     mov dx,offset my_24
  334.     int 21h
  335.     pop es                ;restore ES
  336.     ret
  337. ioset    endp
  338. ;
  339. ioreset    proc near
  340.     assume    ds:nothing
  341.     mov ax,2524h            ;restore interrupt 24h vector
  342.     lds dx,their_24h
  343.     int 21h
  344.     mov ax,2523h            ;restore interrupt 23h vector
  345.     lds dx,their_23h
  346.     int 21h
  347.     mov ax,251Bh            ;restore interrupt 1Bh vector
  348.     lds dx,their_1Bh
  349.     int 21h
  350.     ret
  351. ioreset    endp
  352.  
  353. csegend
  354.  
  355.  
  356.     pubproc    start_back
  357.     push    ds
  358.     mov    ax,cs
  359.     mov    ds,ax
  360.     dscode
  361. ;
  362. ;Remember our psp.
  363. ;
  364.     mov ah,51h            ;get current PSP segment
  365.     int 21h
  366.     mov my_psp,bx            ;save it
  367.  
  368. ;
  369. ;Determine which version of DOS is running.
  370. ;
  371. init3:
  372.     mov ah,30h            ;DOS function 30h
  373.     int 21h
  374.     mov dos_version,al        ;major version number
  375. ;
  376. ;Get and save the address of the INDOS flag.
  377. ;
  378.     mov ah,34h            ;function 34h
  379.     int 21h                ;get address
  380.     mov dos_segment,es        ;save segment
  381.     mov indos_offset,bx        ;save offset
  382. ;
  383. ;Get and save the address of the critical error flag.
  384. ;
  385.     mov ax,3E80h            ;CMP opcode
  386.     mov cx,2000h            ;max search length
  387.     mov di,bx            ;start at INDOS address
  388. init4:
  389.     repne scasw            ;do the search
  390.     jcxz init5            ;branch if search failed
  391.     cmp byte ptr es:[di+5],0BCh    ;verify this is it
  392.     je found            ;branch if it is
  393.     jmp init4            ;resume loop if it's not
  394. init5:
  395.     mov cx,2000h            ;search again
  396.     inc bx                ;search odd addresses this time
  397.     mov di,bx
  398. init6:
  399.     repne scasw            ;look for the opcode
  400.     jcxz notfound            ;not found if loop expires
  401.     cmp byte ptr es:[di+5],0BCh    ;verify this is it
  402.     je found
  403.     jmp init6
  404. notfound:
  405.     pop    ds
  406.     xor    ax,ax
  407.     ret
  408. found:
  409.     mov ax,es:[di]            ;get flag offset address
  410.     mov errflag_offset,ax        ;save it
  411.  
  412. ;
  413. ;Save and replace all required interrupt vectors.
  414. ;
  415.   if 0
  416.     mov ax,3508h            ;get interrupt 8 vector
  417.     int 21h
  418.     mov their_8h.offs,bx            ;save it
  419.     mov their_8h.segm,es
  420.     mov ah,25h            ;point it to the timer routine
  421.     mov dx,offset timer
  422.     int 21h
  423.   endif
  424.  
  425.     mov ax,3510h            ;get interrupt 10h vector
  426.     int 21h
  427.     mov their_10h.offs,bx            ;save it
  428.     mov their_10h.segm,es
  429.     mov ah,25h            ;point it to video
  430.     mov dx,offset video
  431.     int 21h
  432.  
  433.     mov ax,3513h            ;get interrupt 13h vector
  434.     int 21h
  435.     mov their_13h.offs,bx            ;save it
  436.     mov their_13h.segm,es
  437.     mov ah,25h            ;point it to my_13
  438.     mov dx,offset my_13
  439.     int 21h
  440.  
  441.     mov ax,3528h            ;get interrupt 28h vector
  442.     int 21h
  443.     mov their_28h.offs,bx            ;save it
  444.     mov their_28h.segm,es
  445.     mov ah,25h            ;point it to my_28
  446.     mov dx,offset my_28
  447.     int 21h
  448.  
  449.     mov ax,3521h            ;get interrupt 21h vector
  450.     int 21h
  451.     mov their_21h.offs,bx            ;save it
  452.     mov their_21h.segm,es
  453.     mov ah,25h            ;point it to my_21
  454.     mov dx,offset my_21
  455.     int 21h
  456.  
  457.     pop    ds
  458.     mov    ax,1
  459.     ret
  460.     pend    start_back
  461.  
  462.  
  463.     pubproc    stop_back
  464.     assume    ds:nothing
  465.     push    ds
  466.     mov ax,2521h            ;restore interrupt 21h vector
  467.     lds dx,their_21h
  468.     int 21h
  469.     mov ax,2510h            ;restore interrupt 10h vector
  470.     lds dx,their_10h
  471.     int 21h
  472.     mov ax,2513h            ;restore interrupt 13h vector
  473.     lds dx,their_13h
  474.     int 21h
  475.   if 0
  476.     mov ax,2508h            ;restore interrupt 8 vector
  477.     lds dx,their_8h
  478.     int 21h
  479.   endif
  480.     mov ax,2528h            ;restore interrupt 28h vector
  481.     lds dx,their_28h
  482.     int 21h
  483.     pop    ds
  484.     mov dx,cs
  485.     mov ax,offset tick_counter
  486.     ret
  487.     pend    stop_back
  488.  
  489.   if verify
  490. cseg
  491. check_stack:
  492.     push    ax
  493.     push    cx
  494.     push    dx
  495.     push    si
  496.     push    di
  497.     push    ds
  498.     push    es
  499.  
  500.     mov    ds,cs:intds@
  501.     mov    es,cs:intds@
  502.     mov    cx,verify_len
  503.     mov    si,offset verify_original
  504.     mov    di,offset verify_copy
  505.     repne    cmpsb
  506.     je    check_stack_1
  507.     mov    dx,offset verify_err
  508.     mov    ah,9
  509.     int    21h
  510. check_stack_1:
  511.     pop    es
  512.     pop    ds
  513.     pop    di
  514.     pop    si
  515.     pop    dx
  516.     pop    cx
  517.     pop    ax
  518.     ret
  519. csegend
  520.   endif
  521.  
  522.     end
  523.